package com.google.projectulator;

import java.util.ArrayList;
import java.util.List;

import org.apache.maven.project.MavenProject;

import com.google.projectulator.exception.ProjectulatorCollectionException;
import com.google.projectulator.exception.ProjectulatorConfigurationException;
import com.google.projectulator.exception.UnimplementedFeatureException;


/**
 * ProjectProcessor that gathers projects to process either up or down
 * from the current project.  By default will search up, but can be specified
 * to search down or in both directions as well.  The list loaded into the
 * context will ordered from top down.
 * 
 * @author Lance Woodson
 *
 */
public class DefaultProjectCollector extends BaseProjectulatorDelegate implements ProjectCollector {
	// TODO add strategy for single target.
	public static final String CONFIG_PARAM_NAME = "projectCollector.collectionStrategy";
	public static final String UP_STRATEGY = "up";
	public static final String DOWN_STRATEGY = "down";
	public static final String UP_DOWN_STRATEGY = "up-down";
	private String strategy;
	
	public DefaultProjectCollector() {
		name = "DefaultProjectCollector";
	}
	
	public void init(Config config) {
		log.debug("init called for DefaultProjectCollector");
		
		strategy = config.getOrDefault(CONFIG_PARAM_NAME, UP_STRATEGY);
		
		log.debug("Utilizing " + strategy + " strategy");
	}
	
	

	public List<ProjectState> collect(Context context) throws ProjectulatorCollectionException {
		log.debug("collect called for DefaultProjectCollector");
		List<ProjectState> result = new ArrayList<ProjectState>();
		
		if (strategy == UP_STRATEGY) {
			populateUp(result, context.getOriginalProject().getMavenProject(), null);
		} else if (strategy == DOWN_STRATEGY) {
			executeDownStrategy(context, result);
		} else if (strategy == UP_DOWN_STRATEGY) {
			executeUpDownStrategy(context, result);
		} else {
			throw new ProjectulatorConfigurationException(strategy + " strategy unknown");
		}
		
		log.debug("DefaultProjectCollector collection finished");
		return result;
	}
	
	void populateUp(List<ProjectState> result, MavenProject mp, MavenProject previous) throws ProjectulatorCollectionException {
		if (mp != null) {
			log.debug("Collecting " + mp.getName());
			ProjectState pState = new ProjectState(mp);
			pState.setRelativePath(getRelativePathBetween(mp, previous));
			result.add(0, pState);
			populateUp(result, mp.getParent(), mp);
		}
	}
	
	String getRelativePathBetween(MavenProject target, MavenProject previous) throws ProjectulatorCollectionException {
		String result;
		if (previous == null) {
			result = "pom.xml";
		} else {
			result = previous.getModel().getParent().getRelativePath();
			if (result == null) throw new ProjectulatorCollectionException("No relativeUrl in parent stanza of " + target.getName() + " pom");
		}
		return result;
	}
	
	String getRelativeURLOfParent(MavenProject mp) {
		
		return null;
	}
	
	void executeDownStrategy(Context context, List<ProjectState> result) {
		throw new UnimplementedFeatureException();
	}
	
	void executeUpDownStrategy(Context context, List<ProjectState> result) {
		throw new UnimplementedFeatureException();
	}
	
	public String getStrategy() {
		return strategy;
	}
	
	public void setStrategy(String strategy) {
		this.strategy = strategy;
	}
	
	@Override
	public String toString() {
		return "DefaultProjectCollector(" + name + ")";
	}
}